# @(#) sombuild/README 2.38 2/15/94 16:05:06 [5/15/94 17:51:34]

# 96F8647, 96F8648, 96F8850 (C) Copyright IBM Corp. 1992, 1994
# All Rights Reserved
# Licensed Materials - Property of IBM


AIX Users:
----------

    Immediately following installation you should incorporate the
    contents of /usr/lpp/som/bin/somenv.csh into your .login (csh
    users) or /usr/lpp/som/bin/somenv.sh into your .profile
    (sh/ksh users) as appropriate.


OS/2 Users:
-----------

    If you elected not to update your config.sys file during
    installation, you should now copy the appropriate lines from
    somenv.cmd into your config.sys file.  Be sure to change all
    occurrences of %SOMBASE% to the actual directory where you
    installed SOM, since no symbolic substitution is allowed in
    the config.sys file.

    In the unlikely event that your CONFIG.SYS file contains characters
    following a ^Z (control-Z), the installation program adds lines
    AFTER THE ^Z, causing them to be ignored at boot time.  If your
    CONFIG.SYS file contains a ^Z, ensure that it is the last character
    in the file.


SOMobjects Developer Toolkit Users (AIX and OS/2):
--------------------------------------------------

    If you have just completed the installation process for OS/2,
    you must reboot before executing the procedures described
    next so that the latest SOM.DLL can be used during their
    execution.  AIX users may continue without rebooting (as long
    as no SOM processes are active), but must first switch to
    superuser (using su), then ensure the environment is properly
    setup as follows:

    (for sh and ksh users)
        $ . /usr/lpp/som/bin/somenv.sh
    (and for csh users)
        % source /usr/lpp/som/bin/somenv.csh

    If you intend to program with SOM using the C++ bindings, run
    the 'somxh' command to generate the needed C++ .xh files for
    the classes supplied with the SOMobjects Toolkit.

    If you intend to program with SOM using the C bindings, you
    need to select one of the two possible forms of C bindings:
    the strict CORBA-compliant form in which '*'s are NOT exposed
    in object references, or the OIDL-compatible C++ form in
    which '*'s are visible in object references.  This second
    form is more appropriate if you plan to move your class
    implementations from C to C++ at some future point.  This
    choice will determine how object references will appear in
    all of your C programs.  For example, to declare a reference
    to an instance of class Foo, you would code either

        Foo afoo;    /* Strict CORBA compliant form */

    or

        Foo *afoo;   /* C++ migration or OIDL-compatible form */

    Depending on your choice of coding style, you must run either
    the 'somcorba' command (for the CORBA compliant form) or the
    'somstars' command (for the C++ or OIDL-compatible form).
    These commands will generate an appropriate set of C header
    files for the classes in the SOMobjects toolkit.  If you
    decide to use 'somstars', you should also set the SMADDSTAR
    variable in your local environment.  All subsequent use of
    the SOM Compiler depends on this environment variable to
    indicate the use of the 'somstars' style.  For example,

    For OS/2

        set SMADDSTAR=1

    For AIX

        SMADDSTAR=1; export SMADDSTAR (ksh and sh)
        setenv SMADDSTAR 1 (csh)

    If you later decide to switch from one coding style to the
    other, any C code that you have already written will then
    need to be converted (by you) to the other form.  Also, if
    switching from the 'somstars' style to the 'somcorba' style,
    the SMADDSTAR variable must be removed from your environment.
    Note that all of the sample C programs provided with the
    toolkit assume the use of the CORBA-compliant coding style
    (somcorba).

    If you have elected to install only some of the SOMobjects
    Developer Toolkit components, and later decide to install one
    or more additional SOM components, you will need to repeat
    the somxh/somcorba/somstars procedure after each subsequent
    install.

    There have been many significant enhancements to SOM since
    its first release on OS/2 2.0.  You need to familiarize
    yourself with these by reviewing the documentation available
    for this software before you will be able to make effective
    use of the toolkit.


AIX XL C++/6000 or OS/2 C Set++ Users
-------------------------------------

    The OS/2 makefiles for the toolkit samples are written
    assuming a C Set/2 1.0 C compiler and libraries.  Some of the
    makefiles attempt to link with libraries that are known to
    have been eliminated (actually, merged with other libraries
    -- e.g., dde4sbm) in the C Set++ product or the C Set/2 C/C++
    Beta.  If you are using either of these, you will have to
    modify the makefiles to get rid of the references to the
    missing libraries, or just type <RETURN> when the linker asks
    for the name of a substitute library.

    To build some of the SOMobjects sample programs you must also
    have the OS/2 Programmer's Toolkit installed.

    The SOMobjects Developer Toolkit includes an emitter that
    will produce .brs files that are compatible with the class
    browser included with the AIX XL C++/6000 or the OS/2 C Set++
    products.  To produce a .brs file from a SOM IDL class
    definition, indicate the "brs" emitter in your sc command
    line.  For example,

        sc -sbrs myclass.idl

    This will permit the browsing of a SOM class definition using
    the browser supplied with these products.


On building SOM libraries implemented using C++ on AIX:
------------------------------------------------------

    On AIX, it has been observed that using the "somFindClass" or
    "somFindClsInFile" methods or the AIX "load" system call on shared
    libraries (SOM DLL's) which have been implemented using C++ may
    result in a program crash.  This problem DOES NOT appear when the
    shared library is linked to the application at compile-time.

    Version 1.1.1 of the AIX XL C++ Compiler/6000 provides a command,
    "makeC++SharedLib", which may be used to correctly build a shared
    library implemented in C++ on AIX if this problem occurs.  This
    command must be used instead of the "ld" command, when building a
    SOM library.

    For more information, the "makeC++SharedLib" command is documented in 
    the AIX XL C++ Compiler/6000 User's Guide (publication SC09-1472-01).

    Note:  Version 1.1.1 of the AIX XL C++ Compiler/6000 may require
    program updates to versions of AIX earlier than 3.2.3.


SOM.DLL placement on OS/2
-------------------------

    The install program places the directory containing the SOM
    DLL near the beginning of the LIBPATH statement in your 
    config.sys file.  If you later decide to change the LIBPATH
    statement, you must ensure that the directory containing the
    SOMobjects SOM.DLL always precedes the OS2\DLL directory which
    contains the original SOM.DLL supplied with OS/2.  We do NOT
    recommend replacing the OS/2 SOM.DLL with the new one.  Having
    two directories with a SOM.DLL will permit you to replace one
    copy while using the other, should maintenance ever be 
    necessary.

    Note: because the OS/2 Workplace Shell loads the SOM DLL
    during its initialization, you must have a copy on your local
    machine! If you have installed SOMobjects on a network drive,
    place a copy of the SOMobjects som.dll in a directory on your
    local machine and add that directory to the OS/2 LIBPATH in
    your config.sys file (be sure to place it before the OS2\DLL
    directory).


Known limitations and restrictions
----------------------------------

    SOM Compiler

     1. Mutually recursive IDL structures and unions are not
        currently supported.  The following is an example of
        unsupported mutual recursion:

            struct X;
            struct Y {
                sequence<X> indirectSelf;
            };
            struct X {
                sequence<Y> indirectSelf;
            };

     2. The C bindings do not permit the use of multiple methods
        with the same name that also take an argument of type
        va_list within the same module.  For example, the
        following legal IDL will result in incorrect C usage
        bindings:

            module X {
                interface Y {
                    void foo (in long f, in va_list ap);
                };
                interface Z {
                    void foo (in long f, in va_list ap);
                };
            };

     3. The C++ language bindings are built assuming use of
        the AIX XL C++/6000 compiler or the OS/2 C Set++
        compiler, but other C++ compilers should be able to use
        these bindings as well.  For example, to use BCOS2
        (Borland's C++ compiler for OS/2), use -DSOMLINK=_syscall
        on the compile line, and make sure that SOMobject's
        include directory is consulted before BCOS2/include
        (because BCOS2/include contains older som.h include
        files).

     4. On OS/2 if the SOM Compiler is interrupted by the User
        (using <CTRL> C, for example), it sometimes leaves a
        temporary file with a ".CTN" extension in the temporary
        directory %SMTMP%.  These should be removed periodically.

     5. When direct references to SOMFOREIGN types are made in
        an IDL struct or union, the C/C++ language bindings are
        generated incorrectly.  To refer to a SOMFOREIGN type
        (for example, "somId") in a structure or a union it is
        necessary to supply a secondary typedef for "somId".
        For example:

            #include <somobj.idl>
            struct S1 {
                somId badId;    /* Generates incorrect */
            };                  /*  C/C++ bindings.    */

            #include <somobj.idl>
            typedef somId somId2;
            struct S1 {
                somId2 badId;   /* Ok. */
            };

     6. On OS/2 only "passthru" statements cannot end with \".
        For example:
            passthru C_h = "#define MAX(a,b) \"
                           "    a > b ? a : b";  /* Not valid */
        You can of course use:
            passthru C_h = "#define MAX(a,b) a > b ? a : b";  /* Valid */

        Or place 
            #define MAX(a,b) \
                     a > b ? a : b

        in a file (e.g. "max.h"), and then use:
            passthru C_h = "#include <max.h>";  /* Valid */
        

    Emitter framework

        The installed version of the newemit command generates C
        source files.  You can modify the gen_c.efw,
        gen_emit.efw, and gen_make.efw template files in the
        include directory for C++ usage if desired.


    Persistence framework

     1. When restoring an object with the Persistence Framework,
        the file name specified within a Persistent ID string
        must be identical to the file name used when the object
        was originally initialized.  In general, if you use a
        path as part of the file name in the ID string you should
        consistently use the same path name in all references to
        the file.

        For example, the Persistent ID string
        "SOMPAscii:./file:0" is not equivalent to
        "SOMPAscii:file:0".  Both refer to the same file in the
        current directory but are not equivalent object IDs.  You
        can determine your ID string with the
        sompGetPersistentIdString method.

        If you inadvertently refer to an object with an ID it was
        not initialized with, and it contains embedded objects in
        the same file but with different ID strings, you may
        experience the following behavior.  For example, if you
        attempt to restore object "SOMPAscii:file:0" and that
        object has an embedded object named "SOMPAscii:./file:0":

         -  On OS/2, your process may sit idle for awhile and
            then return a sompException exception with primary
            return code 1 and secondary return code 24 (errno =
            EACCESS).

         -  On AIX, if you are storing your objects in the local
            file system (as opposed to NFS) your process may hang
            indefinitely.

     2. If you instantiate your own Media Interface object
        (either SOMPAscii or SOMPBinary) and pass the
        "open_for_readwrite" and "share" flags on the
        sompInitSpecific method, you will find that the "share"
        flag is ignored.  When files are opened for read/write
        they are always opened for exclusive access.


    Replication framework

     1. Maximum number of replicas is fixed (12).  That is, at
        most 12 processes (equivalently, address spaces) can
        participate in the shared access to a replicated object.

     2. Maximum number of replicated objects per address space is
        fixed (100).

     3. The framework allows at most 5 replicas to come up
        concurrently.  If more are needed, bring them up one
        after another.

     4. The framework relies on socket failures to infer replica
        process failures.  For the framework fault-tolerance to
        work, any user provided socket class implementation
        should provide the same semantics as TCP/IP Sockets.

        The sockets can buffer up to 2K bytes of messages.  If
        the applications have higher rates of messages, then the
        communication system imposes flow control and blocks the
        senders until the receivers have consumed the previous
        messages.  This will result in some replicas getting
        slowed down because their peers are slow.  This condition
        results in seeing the following message from the
        replication framework.  "Waiting for Network Transport to
        be Ready ...".  If the problem persists, one may have to
        increase the buffer sizes used by the network transport
        service.

     5. Replicas rendezvous using the .scf file.  If there is
        contention for this file, each process tries for 3
        seconds and then gives up.  When this happens, an error
        message like "Unable to open SCF after NUM_OPEN_RETRIES
        ???????????" appears and the application must be
        restarted.

     6. The environment variables SOMR_HEARTBEAT and
        SOMR_INTERBEATLIMIT control the recovery duration once a
        replica goes down.  The recovery can be anywhere between
        immediate to 2*SOMR_INTERBEATLIMIT.  Reducing
        SOMR_INTERBEATLIMIT also requires reducing
        SOMR_HEARTBEAT.  Too low a value for SOMR_HEARTBEAT can
        mean poor performance for the first replica and harder
        rendezvous for the other replicas.  On OS/2 the
        recommended minimum value for SOMR_HEARTBEAT is 10
        seconds.  SOMR_INTETBEATLIMIT should be a multiple of
        SOMR_HEARTBEAT.  The default settings (on both AIX and
        OS/2) are SOMR_HEARTBEAT = 30 seconds and
        SOMR_INTERBEATLIMIT = 90 seconds.

     7. The Replication Framework does not automatically deal with
        composited objects (that is, replicated objects nested inside
        a replicated object) in the sense that there is no hierachial
        locking to ensure one-copy serializability on the composite
        (viewed as a whole).  

     8. Objects with composite method parameters that are not
        derived from SOMRLinearizable must use VALUE logging.
        (In other words, operation logging works only with
        primitive data types and linearizable objects.)

     9. The framework is not thread safe.  One cannot invoke
        methods on the framework from multiple threads
        concurrently.

    10. When running on multiple machines, recovery from
        failures and recovery from the presence of obsolete .scf
        files depends on the clocks on various machines being
        synchronized.  One might observe peculiar recovery
        behavior if the clocks are out of sync.

    Here are some common user-error situations you may encounter
    using the Replication Framework and the most likely causes
    for them.

     1. Condition:  Replication initialization fails and the
        copies don't seem to be connected.

        Make sure that you don't have an old .scf file around.
        Before running any replicated application remove old .scf
        files.

     2. Condition:  The program exits with a message like
        "Environment variable SOMSOCKETS not defined.".

        For replication framework to run, this environment
        variable must be set to the name of the Socket
        implementation class.  Refer to the user guide regarding
        dependence on Socket class and DLL.

     3. Condition:  The program exits with a message like
        "Unable to locate class <class name> in SOMIR or failed
        to load the associated dll".

        Typically this message appears when the environment
        variable SOMSOCKETS is set to name a class, but the named
        class does not exist in the Interface Repository.  It
        could also be the case that the SOMIR environment
        variable was set incorrectly.

     4. Condition:  The program fails with a segmentation fault.

        Typically, this occurs when the replicated object class
        is not found in the Interface Repository.  To correct the
        problem, first check if SOMIR is set properly.  If it is
        not, set it and run sc on the .idl file(s) of the
        replicated object(s) with the -u option.  The environment
        variable SOMIR should be set correctly both when sc is
        run and when the replicated application is run.

     5. Condition:  The first copy (i.e., master) comes up, but
        another copy (shadow) fails on the call to somrRepInit.

        Examine the error code from the call.  If it indicates
        UNAUTHORIZED, check the access control permissions on the
        .scf file and make sure the shadow processes can access
        it in the expected mode (i.e., as writers or readers).

     6. Condition:  Even the first copy does not come up (i.e.,
        somrRepInit fails), and there is an old .scf file in the
        current directory for the replicated object being brought
        up.

        Make sure that the process has appropriate access
        permissions on the .scf file.  Also make sure that the
        timestamp on the file is older than the current time.
        (It seems like the timestamp should never be newer than
        the current time, but it can happen if a remote machine
        (with a different clock) creates this file when the drive
        containing the file is mounted on the remote machine.)
        See the note about synchronization of clocks above.


    Distributed SOM

     1. DSOM allocates system resources during its execution,
        such as segments, semaphores, and message queues.
        Normally, these system resources are freed and returned
        to the system when SOMD_Uninit is called.  However, on
        AIX, if the DSOM program terminates without calling
        SOMD_Uninit, the resources often remain allocated.  (On
        OS/2, the resources are automatically returned when the
        program terminates.)

        On AIX, there is a script provided (in $SOMBASE/bin)
        which will clean up IPC resources allocated to a
        particular user.  The script, called "cleanipc", takes a
        user id as an argument and removes any IPC resources
        allocated to that user.  The syntax is:

            cleanipc [ user-id ]

        If no user-id is specified, the environment variable
        $USER is queried to get the user's id.

        The cleanipc script should be run AFTER all DSOM
        processes have been killed.

     2. The function prototype for SOMD_RegisterCallback is
        missing from DSOM include files.  To use this function
        (with EMan), include the following C prototype in your
        program:

            #include <eman.h>
            #ifdef __IBMC__
              #pragma linkage(SOMD_RegisterCallback, system)
            #endif
            SOMEXTERN void SOMD_RegisterCallback(SOMEEMan eman,
                EMRegProc *func);

        For C++ or "non-strict" C usage, use the prototype:

             SOMEXTERN void SOMD_RegisterCallback(SOMEEMan* eman,
                 EMRegProc *func);

     3. On AIX, the use of "floats" as input arguments in a
        method call may result in a segmentation violation when
        the call is executed.  This problem is apparently due to
        an incompatibility between the way float arguments are
        represented on the call stack (by some levels of the C
        compiler), and the way float arguments are extracted from
        the call stack using varargs macros in somDispatch calls.

        If this problem is encountered in your application,
        arguments of type "double" may be used instead of
        "float".

     4. The DSOM daemon, somdd terminates with "exception COMM_FAILURE", 
        if the environment variable SOMSOCKETS is not set in Workgroup
        DSOM, even if you are running a single-machine application. SOMSOCKETS
        should only be required if running multiple-machine applications.

     5. The "OBJECT_NIL" literal is not supported in this
        release of DSOM.  To get a nil object reference, simply
        create a SOMDObject.  This is done by calling
        "SOMDObjectNew()" in C, or "new SOMDObject" in C++.

     6. The OUT_LIST_MEMORY, IN_COPY_VALUE, and DEPENDENT_LIST
        flags, used with the Dynamic Invocation Interface, are
        not yet supported.

     7. Concurrent updates to the Implementation Repository
        are not properly serialized currently, and can conflict.

     8. See the section on "Troubleshooting Hints" in section
        6.10 of the SOMobjects Developer Toolkit User's Guide for
        help in debugging and testing of DSOM programs.


    Event Management framework

        Error situations and possible causes:

     1. Situation: The application hangs inside EMan.

        Cause:  You probably have an older version of TCPIP.
        Make sure that all TCPIP CSD's specified in the
        installation package for this product are applied.

     2. Situation:  EMan processes new event registrations fine
        for a while and then seems to ignore all new
        registrations and client events (e.g., enqueued client
        events are not delivered to the callbacks).

        Cause:  You probably called someUnRegister with an
        illegal value (perhaps 0).  Check the source and make
        sure that all calls to someUnRegister are made with
        registration id's returned by the Event Manager
        previously.

     3. Situation:  On OS/2, the event manager is used with two
        threads, one to execute someProcessEvents and the other
        to make registrations/unregistrations etc.  When the
        application decides to terminate, the thread making
        registrations calls someShutDown on EMan and tries to
        terminate the program.  EMan hangs.  It looks like EMan
        is still busy doing something.

        Cause:  Probably one of the threads did a DosExit on self
        (THREAD not PROCESS) and the other thread is stuck in the
        communication subsystem like TCPIP.  The fix is to do a
        DosExit on the PROCESS (see the sample program for event
        management framework).


SOM 1.0 OIDL Users
------------------

    If you need to recompile an OIDL class that overrides
    the somDumpSelf or somDumpSelfInt methods, you will need
    to change the type of the "level" parameter in the
    function definition in your C source program from "int"
    to "long".  For example, if your original class source
    program had a somDumpSelfInt method override procedure
    similar to

        SOM_Scope void SOMLINK somDumpSelfInt(
            <className> *somSelf, int level)
        {
        ...
        }

    Change it to read:

        SOM_Scope void SOMLINK somDumpSelfInt(
            <className> *somSelf, long level)
        {
        ...
        }

    Since both types "int" and "long" require 4 bytes on OS/2,
    this does not affect the binary interface of your class.


Errors in the Documentation:
----------------------------
    
    "SOMobjects Developer Toolkit Users Guide", 4-70

    4.
       For AIX: Using the object files and the export file ...

           ld -o abc.dll -bE:abc.exp -e SOMInitModule -H512 -T512 \
               a.o b.o c.o initfunc.o -lc -l$SOMBASE/lib/somtk

       SHOULD READ:
       For AIX: Using the object files and the export file ...

           ld -o abc.dll -bE:abc.exp -e SOMInitModule -H512 -T512 \
               a.o b.o c.o initfunc.o -lc $SOMBASE/lib/libsomtk.a
